import { LoadScriptAsync } from './LoadScriptAsync';

/**
 * Options to load the associated Glslang library
 */
export interface GlslangOptions
{
    /**
     * Defines an existing instance of Glslang (useful in modules who do not access the global instance).
     */
    glslang?: any;
    /**
     * Defines the URL of the glslang JS File.
     */
    jsPath?: string;
    /**
     * Defines the URL of the glslang WASM File.
     */
    wasmPath?: string;
}

export class GlslangWASM
{
    private static readonly _GLSLslangDefaultOptions: GlslangOptions = {
        jsPath: 'https://preview.babylonjs.com/glslang/glslang.js',
        wasmPath: 'https://preview.babylonjs.com/glslang/glslang.wasm',
    };
    private static _glsl: any = null;

    compileGLSL(newCode: string, type: string)
    {
        return GlslangWASM._glsl.compileGLSL(newCode, type);
    }

    async initGlslang(glslangOptions?: GlslangOptions): Promise<void>
    {
        glslangOptions = glslangOptions || {};
        glslangOptions = {
            ...GlslangWASM._GLSLslangDefaultOptions,
            ...glslangOptions,
        };

        if (glslangOptions.glslang)
        {
            GlslangWASM._glsl = glslangOptions.glslang;

            return Promise.resolve();
        }

        if (glslangOptions.jsPath && glslangOptions.wasmPath)
        {
            await LoadScriptAsync(glslangOptions.jsPath);
        }

        if ((globalThis as any).glslang)
        {
            GlslangWASM._glsl = await (globalThis as any).glslang(glslangOptions.wasmPath);

            return Promise.resolve();
        }

        return Promise.reject('gslang is not available.');
    }
}

